package cn.javase.concurrent._相关原理._volatile原理._DCL问题;

public class Singleton {


    private Singleton() { }

    /* 解决方法：需要加上volatile才能防止指令重排 */
    private static volatile Singleton INSTANCE = null;


    public static Singleton getInstance() {
        if(INSTANCE == null) { // t2
            // 首次访问会同步，而之后的使用没有 synchronized
            synchronized(Singleton.class) {
                if (INSTANCE == null) { // t1
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }

    /*
        以上的实现特点是：
            懒惰实例化
            首次使用 getInstance() 才使用 synchronized 加锁，后续使用时无需加锁
            有隐含的，但很关键的一点：第一个 if 使用了 INSTANCE 变量，是在同步块之外
     */
}
